//this map use stl map and  inhert from GMap
//andycai_sc implement 2011-04-17

#ifndef GStdStandMap_H
#define GStdStandMap_H

#include "GTpl/IGMap.h"

#include <map>

using std::map;
using std::pair;
using std::iterator;

template<typename Key, typename Value>
class GStandMap : public GMap<Key, Value>
{
public:
    GStandMap() {}
    virtual ~GStandMap() {}

    typename GMap<Key, Value>::IterPtr insert(const Key& key, const Value& value);
    int erase(const Key& key);
    void erase(typename GMap<Key, Value>::IterPtr position);
    typename GMap<Key, Value>::IterPtr find(const Key& key);

    typename GMap<Key, Value>::IterPtr begin();
    typename GMap<Key, Value>::IterPtr end();

private:
    map<Key, Value> m_stdMap;
    class SIterator : public GMap<Key, Value>::Iterator
    {
    public:
        SIterator(const typename map<Key, Value>::iterator& it) { m_iter = it; }
		SIterator(const SIterator& sit) { m_iter = sit.m_iter; }
        virtual ~SIterator() {}
		typename GMap<Key, Value>::Iterator* clone();
        const Key& getKey();
        Value& getValue();
        typename GMap<Key, Value>::Iterator& operator++();
        typename GMap<Key, Value>::Iterator& operator++(int);
        typename GMap<Key, Value>::Iterator& operator--();
        typename GMap<Key, Value>::Iterator& operator--(int);
        bool operator==(const typename GMap<Key, Value>::Iterator&) const;
        bool operator!=(const typename GMap<Key, Value>::Iterator&) const;

        typename map<Key, Value>::iterator getOrigIter() const
        {
            return m_iter;
        }
    private:
        typename map<Key, Value>::iterator m_iter;
    };
};

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMap<Key, Value>::insert(const Key& key, const Value& value)
{
    pair< typename map<Key, Value>::iterator, bool > rp = m_stdMap.insert(typename map<Key, Value>::value_type(key, value));
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(rp.first));
    return itPtr;
}

template<typename Key, typename Value>
int GStandMap<Key, Value>::erase(const Key& key)
{
    return m_stdMap.erase(key);
}

template<typename Key, typename Value>
void GStandMap<Key, Value>::erase(typename GMap<Key, Value>::IterPtr position)
{
    SIterator* sIt = dynamic_cast<SIterator*>(position.get());
    assert(sIt != 0);
    m_stdMap.erase(sIt->getOrigIter());
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMap<Key, Value>::find(const Key& key)
{
    typename map<Key, Value>::iterator it = m_stdMap.find(key);
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMap<Key, Value>::begin()
{
    typename map<Key, Value>::iterator it = m_stdMap.begin();
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMap<Key, Value>::end()
{
    typename map<Key, Value>::iterator it = m_stdMap.end();
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator* GStandMap<Key, Value>::SIterator::clone()
{
	return new SIterator(*this);
}

template<typename Key, typename Value>
const Key& GStandMap<Key, Value>::SIterator::getKey()
{
    return m_iter->first;
}

template<typename Key, typename Value>
Value& GStandMap<Key, Value>::SIterator::getValue()
{
    return m_iter->second;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMap<Key, Value>::SIterator::operator++()
{
    m_iter++;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMap<Key, Value>::SIterator::operator++(int)
{
    ++m_iter;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMap<Key, Value>::SIterator::operator--()
{
    m_iter--;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMap<Key, Value>::SIterator::operator--(int)
{
    --m_iter;
    return *this;
}

template<typename Key, typename Value>
bool GStandMap<Key, Value>::SIterator::operator==(const typename GMap<Key, Value>::Iterator& it) const
{
    const SIterator& sIt = dynamic_cast<const SIterator&>(it);
    return m_iter == sIt.m_iter;
}

template<typename Key, typename Value>
bool GStandMap<Key, Value>::SIterator::operator!=(const typename GMap<Key, Value>::Iterator& it) const
{
    const SIterator& sIt = dynamic_cast<const SIterator&>(it);
    return m_iter != sIt.m_iter;
}

//----------------------------GStandMultiMap implement------------------------------------

using std::multimap;

template<typename Key, typename Value>
class GStandMultiMap : public GMap<Key, Value>
{
public:
    GStandMultiMap() {}
    virtual ~GStandMultiMap() {}

    typename GMap<Key, Value>::IterPtr insert(const Key& key, const Value& value);
    int erase(const Key& key);
    typename GMap<Key, Value>::IterPtr find(const Key& key);

    typename GMap<Key, Value>::IterPtr begin();
    typename GMap<Key, Value>::IterPtr end();

    typename GMap<Key, Value>::Range equal_range(const Key& key);

private:
    multimap<Key, Value> m_stdMap;
    class SIterator : public GMap<Key, Value>::Iterator
    {
    public:
        SIterator(const typename multimap<Key, Value>::iterator& it) { m_iter = it; }
		SIterator(const SIterator& sit) { m_iter = sit.m_iter; }
        virtual ~SIterator() {}
		typename GMap<Key, Value>::Iterator* clone();
        const Key& getKey();
        Value& getValue();
        typename GMap<Key, Value>::Iterator& operator++();
        typename GMap<Key, Value>::Iterator& operator++(int);
        typename GMap<Key, Value>::Iterator& operator--();
        typename GMap<Key, Value>::Iterator& operator--(int);
        bool operator==(const typename GMap<Key, Value>::Iterator&) const;
        bool operator!=(const typename GMap<Key, Value>::Iterator&) const;
    private:
        typename multimap<Key, Value>::iterator m_iter;
    };
};

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMultiMap<Key, Value>::insert(const Key& key, const Value& value)
{
    typename multimap<Key, Value>::iterator it = m_stdMap.insert(typename multimap<Key, Value>::value_type(key, value));
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
int GStandMultiMap<Key, Value>::erase(const Key& key)
{
    return m_stdMap.erase(key);
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMultiMap<Key, Value>::find(const Key& key)
{
    typename multimap<Key, Value>::iterator it = m_stdMap.find(key);
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMultiMap<Key, Value>::begin()
{
    typename multimap<Key, Value>::iterator it = m_stdMap.begin();
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMultiMap<Key, Value>::end()
{
    typename multimap<Key, Value>::iterator it = m_stdMap.end();
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Range GStandMultiMap<Key, Value>::equal_range(const Key& key)
{
    pair<typename multimap<Key, Value>::iterator, typename multimap<Key, Value>::iterator> eqRet;
    eqRet = m_stdMap.equal_range(key);
    typename GMap<Key, Value>::IterPtr itPtrF(new SIterator(eqRet.first));
    typename GMap<Key, Value>::IterPtr itPtrL(new SIterator(eqRet.second));
    return typename GMap<Key, Value>::Range(itPtrF, itPtrL);
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator* GStandMultiMap<Key, Value>::SIterator::clone()
{
	return new SIterator(*this);
}

template<typename Key, typename Value>
const Key& GStandMultiMap<Key, Value>::SIterator::getKey()
{
    return m_iter->first;
}

template<typename Key, typename Value>
Value& GStandMultiMap<Key, Value>::SIterator::getValue()
{
    return m_iter->second;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMultiMap<Key, Value>::SIterator::operator++()
{
    m_iter++;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMultiMap<Key, Value>::SIterator::operator++(int)
{
    ++m_iter;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMultiMap<Key, Value>::SIterator::operator--()
{
    m_iter--;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMultiMap<Key, Value>::SIterator::operator--(int)
{
    --m_iter;
    return *this;
}

template<typename Key, typename Value>
bool GStandMultiMap<Key, Value>::SIterator::operator==(const typename GMap<Key, Value>::Iterator& it) const
{
    const SIterator& sIt = dynamic_cast<const SIterator&>(it);
    return m_iter == sIt.m_iter;
}

template<typename Key, typename Value>
bool GStandMultiMap<Key, Value>::SIterator::operator!=(const typename GMap<Key, Value>::Iterator& it) const
{
    const SIterator& sIt = dynamic_cast<const SIterator&>(it);
    return m_iter != sIt.m_iter;
}

#endif // GStandMap_H
